package com.caj.service;

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

@Service
public class OrderService {

    //模拟远程调用
    @Autowired
    private RemoteService remoteService;

    public JSONObject order(long userId){
        long start = System.currentTimeMillis();

        JSONObject orderInfo = remoteService.createOrder(userId);
        JSONObject goodsInfo = remoteService.dealGoods(orderInfo);
        JSONObject pointsInfo = remoteService.dealPoints(orderInfo);
        JSONObject deliverInfo = remoteService.dealDeliver(orderInfo);

        orderInfo.putAll(goodsInfo);
        orderInfo.putAll(pointsInfo);
        orderInfo.putAll(deliverInfo);

        long end = System.currentTimeMillis();
        System.out.println(end-start);
        return orderInfo;
    }


    /*
        前提：三个任务没有前后的关联逻辑，可以同时执行
        开启三个线程同时执行，减少并行的耗时。
     */
    public JSONObject orderMultiThread(long userId) {

        long start = System.currentTimeMillis();
        JSONObject orderInfo = remoteService.createOrder(userId);

        //处理库存
        Callable<JSONObject> goodsCall = new Callable<JSONObject>(){
            @Override
            public JSONObject call() throws Exception {
                JSONObject goodsInfo = remoteService.dealGoods(orderInfo);
                return goodsInfo;
            }
        };
        //新增积分
        Callable<JSONObject> pointsCall = new Callable<JSONObject>(){
            @Override
            public JSONObject call() throws Exception {
                JSONObject pointsInfo = remoteService.dealPoints(orderInfo);
                return pointsInfo;
            }
        };
        //发货
        Callable<JSONObject> deliverCall = new Callable<JSONObject>(){
            @Override
            public JSONObject call() throws Exception {
                JSONObject deliverInfo = remoteService.dealDeliver(orderInfo);
                return deliverInfo;
            }
        };

        CajFutureTask<JSONObject> goodsTask = new CajFutureTask<>(goodsCall);
        CajFutureTask<JSONObject> pointsTask = new CajFutureTask<>(pointsCall);
        CajFutureTask<JSONObject> deliverTask = new CajFutureTask<>(deliverCall);

        Thread thread1 = new Thread(goodsTask);
        Thread thread2 = new Thread(pointsTask);
        Thread thread3 = new Thread(deliverTask);
        thread1.start();
        thread2.start();
        thread3.start();


        try {
            orderInfo.putAll(goodsTask.get());
            orderInfo.putAll(pointsTask.get());
            orderInfo.putAll(deliverTask.get());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        long end = System.currentTimeMillis();
        System.out.println(end-start);

        return orderInfo;
    }

    class Request {
        JSONObject object;
        CompletableFuture<JSONObject> future;
    }
    LinkedBlockingQueue<Request> queue = new LinkedBlockingQueue<>();

    public JSONObject orderFastbatch(long userId) throws ExecutionException, InterruptedException {
        JSONObject orderInfo = remoteService.createOrderFast(userId);
        CompletableFuture<JSONObject> future = new CompletableFuture<>();
        Request request = new Request();
        request.object = orderInfo;
        request.future = future;
        queue.add(request);
        return future.get();
    }

    //在依赖注入后，对象投入使用前执行
    @PostConstruct
    public void doBiz(){
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                int size = queue.size();
                if(size == 0)
                    return;
                //一次最多执行100条
                if(size > 100)
                    size = 100;
                ArrayList<JSONObject> reqList = new ArrayList<>();
                ArrayList<Request> requestList = new ArrayList<>();
                for (int i = 0; i < 100; i++) {
                    Request request = queue.poll();
                    reqList.add(request.object);
                    requestList.add(request);
                }

                List<JSONObject> rspList = remoteService.dealGoodsFastBatch(reqList);
                System.out.println("调用批量接口,本地组装的数据："+size+"条");

                for (JSONObject rsp : rspList) {
                    for (Request req : requestList) {
                        if(rsp.get("orderId").equals(req.object.get("orderId"))){
                            req.future.complete(rsp);
                        }
                    }
                }
            }
        }, 1000, 50, TimeUnit.MILLISECONDS);
    }
}
